/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package exmtgproj;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Mycket av koden här används bara till spelet som just nu är NYI..
 * @author marcus ahlen
 */
public class Card implements Statics, Serializable, Targetable {

    String name = null;                                     //Name
    int id;                                                 //ID
    String edition;                                         //Edition
    byte owner;                                             //Player owner
    byte controller;                                        //Player controller
    //String oracle = null;                                          //Oracle text
    boolean legendary = false;                              //isLegendary
    boolean type[] = new boolean[TYPES];                  //Types
    ArrayList<String> subtype = new ArrayList<String>();    //Subtypes
    String rarity;
    Ability cast = null;                           //manaCost??
    ArrayList<Ability> abilities = new ArrayList<Ability>();//ActivatedAbilities
    ArrayList<Ability>[] events = new ArrayList[EVENTS];    //TriggeredAbilities
    ArrayList<Ability> statics = new ArrayList();           //StaticAbilities
    boolean[] color = new boolean[COLORS];                       //Colors
    boolean basic;
    Card original;
    transient Image image = Images.noimage.getScaledInstance(240, 340, Image.SCALE_SMOOTH);

    public boolean mono() {                                 //isMonoColored
        byte colors = 0;
        for (byte i = 1; i < color.length; i++) {
            if (color[i]) {
                colors++;
            }
        }
        return colors == 1;
    }
    boolean sickness = false;                               //AffectedBySickness
    boolean attacking = false;                              //isAttacking
    boolean blocking = false;                               //isBlocking
    boolean blocked = false;                                //isBlocked
    boolean tapped = false;                                 //isTapped
    boolean facedown = false;
    boolean marked = false;
    byte turns = 0;                                         //turns in play
    boolean attack1 = false;                                //first strike damage
    boolean attack2 = true;                                 //normal damage
    int power = 0;                                         //power
    int tempPower = 0;                                     //endofturn power
    int toughness = 0;                                     //toughness
    int tempToughness = 0;                                 //endofturn toughness

    public byte getPower() {                                //total power
        return (byte) (power + tempPower + counter[plus] - counter[minus]);
    }

    public byte getToughness() {                            //total toughness
        return (byte) (toughness + tempToughness + counter[plus] - counter[minus]);
    }
    byte x = 0;                                             //what X stands for
    /*byte y = 0;                                           //what Y stands for
    byte z = 0;                                             //what Z stands for */
    CardList equippedWith = new CardList();         //Equipments
    CardList attachedWith = new CardList();         //Auras
    byte prevZone = deck;                                   //Previous zone (hasBeenMoved();)
    byte zone = deck;                                       //Current zone
    boolean targeted;                                       //isTarget of a spell/ability
    private boolean markedForDestruction;                   //remove maybe??
    boolean targetable = true;                              //hasShroud mm
    byte assignedDamage = 0;                                //assigned damage
    byte prevent = 0;                                       //prevent x damage
    byte prevented = 0;                                     //prevented damage taken??
    byte redirect = 0;                                      //redirect x damage to redirectTo
    byte redirected = 0;                                    //redirected damage taken??
    Card[] redirectTo = null;                               //what the redirected damage will be redirected to
    byte damageDone = 0;                                    //damage done
    boolean regenerated;                                    //isRegenerated
    byte[] counter = new byte[COUNTERS];                    //counters
    boolean flying = false;                                 //Keyword: Flying
    boolean haste = false;                                  //Keyword: Haste
    boolean persist = false;                                //Keyword: Persist
    boolean wither = false;                                 //Keyword: Wither
    boolean lifelink = false;                               //Keyword: Lifelink
    boolean firststrike = false;                            //Keyword: First Strike
    boolean doublestrike = false;                           //Keyword: Double Strike
    boolean[] protection = new boolean[6];                  //Keyword: Protection from Color
    boolean[] protectiont = new boolean[6];                 //Keyword: Protection from Type
    boolean deathtouch = false;                             //Keyword: Deathtouch
    boolean reach = false;                                  //Keyword: Reach
    boolean unblockable = false;                            //Keyword: Unblockable
    boolean fear = false;                                   //Keyword: Fear
    boolean changeling = false;                             //Keyword: Changeling
    boolean trample = false;                                //Keyword: Trample
    boolean vigilance = false;                              //Keyword: Vigilance
    boolean shroud = false;                                 //Keyword: Shroud
    boolean[] landwalk = new boolean[6];                    //Keyword: Landwalk

    public Card() {
        init();
    }

    public Card(String n) {
        name = n;
        init();
    }

    /**
     * initiering
     */
    public void init() {
        for (ArrayList<Ability> a : events) {
            a = new ArrayList<Ability>();
        }
    }

    public void initImg() {
        image = Images.getCard(this);
    }

    /**
     * initiering för kortet som gör spelaren till ägare av kortet och skapar en
     * kopia av kortet för att hålla ordning på värden som förändras under spelets gång NYI
     * @param player
     */
    void init(byte player) {
        owner = player;
        original = getValues();
    }

    /**
     * NYI
     * @param card the card that is thatgeting this
     * @return true if it can be targeted
     */
    public boolean target(Card card) {
        return !shroud && !hasProtectionFrom(card);
    }

    public boolean hasProtectionFrom(Card c) {
        for (int i = 1; i < COLORS; i++) {
            if (c.cast.cost[i] > 0 && protection[i]) {
                return true;
            }
        }
        return false;
    }

    public void moveTo(byte zone) {
        this.zone = zone;
    }

    /**
     * Används för att kunna skapa kopior av korten NYI
     * @return
     */
    public Card getValues() {
        Card copy = new Card();
        copy.id = id;
        copy.name = name;
        copy.edition = edition;
        copy.owner = owner;
        copy.legendary = legendary;
        copy.basic = basic;
        copy.type = type;
        copy.subtype = subtype;
        copy.rarity = rarity;
        copy.cast = cast;
        copy.abilities = abilities;
        copy.events = events;
        copy.statics = statics;
        copy.color = color;
        //TODO more;

        return copy;
    }

    public int getRarityValue() {
        if (rarity.equalsIgnoreCase("common")) {
            return 0;
        } else if (rarity.equalsIgnoreCase("uncommon")) {
            return 1;
        } else if (rarity.equalsIgnoreCase("rare")) {
            return 2;
        } else if (rarity.equalsIgnoreCase("mythic rare")) {
            return 3;
        }
        return -1;
    }

    public void draw(Graphics g, int x, int y, int w, int h, boolean highlight) {

        boolean darken = false;
        Image img = Images.back;
        if (!facedown) {
            img = image;
            darken = marked;
        }

        if (highlight) {
            g.drawImage(Images.highlight, x - SpelPlan.cardSpace, y - SpelPlan.cardSpace, w + SpelPlan.cardSpace * 2, h + SpelPlan.cardSpace * 2, null);
        }
        g.setColor(Color.black);
        g.fillRect(x, y, w, h);
        if (img != null) {
            if(img!=Images.noimage){
            g.drawImage(img, x, y, w, h, null);
            }else{
                g.setColor(Color.white);
                g.drawString(name, x+h/2, y);
            }
            if (darken) {
                g.drawImage(Images.overlay, x, y, w, h, null);
            }
        }
    }

    public void draw(Graphics g, Rectangle r,boolean h) {
        draw(g, (int) r.getX(), (int) r.getY(), (int) r.getWidth(), (int) r.getHeight(),h);
    }
}
